﻿
using System;
using SerialPortExamples;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using static SerialPortExamples.Logger;
using System.Windows;
using OfficeOpenXml;
using System.IO;
using System.Windows.Documents;
using SerialPortExample.Excel;
using System.Timers;

namespace ProtocolImpl.Rs232
{
    public class SerialPortSetting : IDisposable
    {
        private SerialPort serialPort;
        private Logger logger = Logger.GetInstance();
        private bool isOpen = false;
        private DateTime lastWriteDateTime;//记录上次写入Excel的时间，
        private const int IntervalMiliseconds = 30000;
        int count = 0;
        //public static string[] Ports { get; set; } = SerialPort.GetPortNames();
        //private string buffer;
        public SerialPortSetting(SerialPort serialPort)
        {
            lastWriteDateTime = DateTime.Now;//初始化为当前时间
            this.serialPort = serialPort;
        }
        //private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        //{
        //    logger.WriteLog("开始接收数据");
        //    SerialPort sp = (SerialPort)sender;
        //    string data = sp.ReadExisting();
        //    //buffer = data;
        //    logger.WriteLog(data);
        //}
        public void Dispose()
        {
            serialPort.Close();
            serialPort.Dispose();
        }
        public void Init()
        {
            logger.WriteLog("COM初始化成功");
            if (!isOpen)
            {
                serialPort.Open();
                isOpen = true;
            }
            //serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
        }
        public int Send(SerialPortExamples.Protocol protocol)
        {

            //logger.WriteLog("开始发送数据");
            byte[] data = protocol.ToByteArray();
            //logger.WriteByteArray(data);
            //logger.WriteLog("Time:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:FFFFFF"));
            serialPort.Write(data, 0, data.Length);
            Thread.Sleep(800);
            return data.Length;
        }
        public (double[], double[], ushort) Receive()
        {
            DateTime date = DateTime.Now;
            // 解析报文，数据从24开始，到72截止
            string timeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            int start = 24; // 数据起始位
            int length = 105; //暂时固定为79，后续如协议有变动需要进行更改

            byte[] buffer = new byte[length];
            int bytesRead = 0;
            while (bytesRead < length)
            {
                 var read = serialPort.Read(buffer, bytesRead, length - bytesRead);
                 bytesRead += read;
            }
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 20; i > 12; i--)
            {
                stringBuilder.Append(buffer[i].ToString());
            }
            
            int dataLength = Convert.ToInt32(stringBuilder.ToString());
            if (dataLength < 30 || dataLength > length)
            {
                return (null, null, default(ushort));
            }

            var _buffer = buffer.AsSpan();
            Span<byte> data = _buffer.Slice(start, 48);
            Span<double> temperatures = stackalloc double[24];

            // 拆分byte，每两个byte代表一个site的温度
            for (int i = 0; i < data.Length; i += 2)
            {
                int highByte = data[i];
                int lowByte = data[i + 1];
                int temperature = (highByte << 8) | lowByte;
                temperatures[i / 2] = temperature;
            }
            var targetTemperature = BitConverter.ToUInt16(_buffer.Slice(74,2));
            start += 48 + 4; // 跳过温度+目标温度
            data = _buffer.Slice(start, 24);
            Span<double> dutyCycles = stackalloc double[24];
            for (int i = 0; i < data.Length; i++)
            {
                dutyCycles[i] = data[i] / 2.0;
            }
            if(DateTime.Now - lastWriteDateTime>TimeSpan.FromMilliseconds(IntervalMiliseconds))
            {
                try
                {
                    Excel.Write(temperatures);
                    lastWriteDateTime = DateTime.Now;
                }
                catch (InvalidOperationException ex)
                {
                    MessageBox.Show("数据保存失败，Excel文件被占用中，请先解除占用");
                }
            }
            return (temperatures.ToArray(), dutyCycles.ToArray(), targetTemperature);
        }
    }
}
